<?php

namespace app\api\services;

use app\admin\model\Technician;
use app\admin\model\UserMoneyLog;
use app\api\model\FareOrder;
use app\api\model\Order;
use ba\PayLib;
use Exception;
use think\facade\Db;
use think\facade\Log;
use Yansongda\Pay\Pay;

class Refund
{

    protected static string|null $out_trade_no = null; //系统交易订单号
    protected static string|null $transaction_id = null; //微信支付交易订单号
    protected static string|null $out_refund_no = null; //商户退款单号
    protected static string|null $refund_id = null; //微信支付退款号
    protected static string|null $refund_amount = null; //退款金额（元）
    protected static string|null $refund_total = null; //订单实际支付金额（元）
    protected static $orderInfo = null; //订单模型
    protected static int $refundOrderID = 0; //退款自增id

    protected static string|null $success_time = null; //退款成功时间

    public function __construct ($out_trade_no, $transaction_id)
    {
        self::$out_trade_no = $out_trade_no;
        self::$transaction_id = $transaction_id;
        self::$out_refund_no = 'RF' . date('YmdHis') . time() . rand(1000, 9999);
        #查询订单
        $orderModel = new Order();
        $orderInfo = $orderModel->where('order_sn', self::$out_trade_no)->find();
        if (empty($orderInfo)) {
            throw new Exception('handle 订单不存在 order_sn：' . self::$out_trade_no . ' 支付交易号 ' . self::$transaction_id);
        }
        self::$orderInfo = $orderInfo;
        $this->handle();
    }


    /**
     * 处理订单
     * @return void
     */
    protected function handle (): void
    {
        #退款金额
        self::$refund_amount = self::$orderInfo->service_reality_price;
        self::$refund_total = self::$orderInfo->service_reality_price;
        $deductMoney = 0;
        $fare_price = 0;
        if (self::$orderInfo->order_state == 'SetOut' || self::$orderInfo->order_state == 'Reach') {
//            #查看技师出行是否免费
//            $FareOrder = FareOrder::where('order_id', self::$orderInfo->id)->find();
//            if (!empty($FareOrder)) {
//                #支付车费
//                $fare_price = $FareOrder->fare_price;
//                $FareOrder->fare_state = 'Paid';
//                $FareOrder->fare_pay_price = $FareOrder->fare_price;
//                $FareOrder->fare_pay_time = date('Y-m-d H:i:s', time());
//                $FareOrder->fare_technician_id = 'RF' . date('YmdHis') . time() . rand(1000, 9999);
//                $FareOrder->fare_pay_state = self::$orderInfo->pay_way;
//                $FareOrder->sava();
//            }
            #订单支付金额扣除用户违约金
            $user_liquidated_damages = bcdiv(get_sys_config('user_liquidated_damages'), "100", 2);//违约金百分比
            $deductMoney = bcmul(self::$orderInfo->service_reality_price, $user_liquidated_damages, 2);
            #加上车费
            $fare_price = self::$orderInfo->fare_price;
            self::$refund_amount = bcsub(self::$orderInfo->service_reality_price, bcadd($deductMoney, self::$orderInfo->fare_price, 2), 2);
        }


        #备注
        $remarks = '退款：违约金： ' . $deductMoney . '元 车费：' . $fare_price . '元';

        #记录退款
        $refundOrderModel = new \app\common\model\RefundOrder();
        $refundOrderModel->order_id = self::$orderInfo->id;
        $refundOrderModel->refund_amount = self::$refund_amount;
        $refundOrderModel->refund_total = self::$refund_total;
        $refundOrderModel->out_trade_no = self::$out_refund_no;
        $refundOrderModel->refund_type = self::$orderInfo->pay_way;
        $refundOrderModel->state = 'NotRefund'; //未退款
        $refundOrderModel->create_time = date('Y-m-d H:i:s', time());
        $refundOrderModel->remarks = $remarks;
        $refundOrderModel->deduct_money = $deductMoney;
        $refundOrderModel->save();

        self::$refundOrderID = $refundOrderModel->id;
    }


    /**
     * 余额退款
     * @return void
     */
    public function balance (): void
    {
        Log::error('余额退款' . self::$out_trade_no . ' 退款金额 ' . self::$refund_amount);
        #增加用户余额
        $userModel = new \app\common\model\User();
        $userInfo = $userModel->where('id', self::$orderInfo->user_id)->find();
        $userInfo->money = bcadd($userInfo->money, self::$refund_amount, 2);
        $userInfo->save();
        #增加到余额变动表
        $UserMoneyLogModel = new UserMoneyLog();
        $userMoneyLog = $UserMoneyLogModel->where('user_id', self::$orderInfo->user_id)->order('create_time', 'desc')->find();
        $UserMoneyLogModel->before = 0;
        if (!empty($userMoneyLog)) {
            $UserMoneyLogModel->before = $userMoneyLog->after;
        }
        $UserMoneyLogModel->user_id = self::$orderInfo->user_id;
        $UserMoneyLogModel->money = self::$refund_amount;
        $UserMoneyLogModel->after = bcadd($userMoneyLog->before, self::$refund_amount, 2);
        $UserMoneyLogModel->memo = '订单退款 ' . self::$out_trade_no;
        $UserMoneyLogModel->create_time = date('Y-m-d H:i:s', time());
        $UserMoneyLogModel->type = 1;
        $UserMoneyLogModel->save();
        #修改订单状态
        $this->editRefundOrderState();
    }


    /**
     * 微信退款
     * @param $action
     * @return void
     * @throws \Yansongda\Pay\Exception\ContainerException
     * @throws \Yansongda\Pay\Exception\InvalidParamsException
     * @throws \Yansongda\Pay\Exception\ServiceNotFoundException
     */
    public function wechat ($action = 'jsapi'): void
    {
        #微信支付 JSApi支付
        $order = [
            'out_trade_no'   => self::$out_trade_no,
            'transaction_id' => self::$transaction_id,
            'out_refund_no'  => self::$out_refund_no,
            'amount'         => [
                'refund'   => self::$refund_amount * 100, //分
                'total'    => self::$refund_total * 100,//分
                'currency' => 'CNY',
            ],
            '_action'        => $action, // jsapi 退款，默认

        ];
        $result = Pay::wechat(PayLib::getConfig())->refund($order);
        Log::info('系统支付订单号 ' . self::$out_trade_no . ' 退款信息 ' . json_encode($result));

        if ($result['status'] != 'SUCCESS' || $result['status'] != 'PROCESSING') {
            Log::error('退款失败 系统支付订单号 ' . self::$out_trade_no . ' 退款信息 ' . json_encode($result));
        }

        self::$refund_id = $result['refund_id'];

        #修改订单状态
        $this->editRefundOrderState();
    }


    /**
     * 修改退款订单状态
     * @return void
     */
    protected function editRefundOrderState (): void
    {
        $refundOrderModel = new \app\common\model\RefundOrder();
        $refundOrderIDInfo = $refundOrderModel->where('id', self::$refundOrderID)->find();
        $refundOrderIDInfo->refund_id = self::$refund_id;
        $refundOrderIDInfo->state = 'Refunded'; //已退款
        $refundOrderIDInfo->success_time = self::$success_time; //退款成功时间
        $refundOrderIDInfo->save();

    }

}